﻿#include "MeasureView/MeasureCircle2Circle.h"
#include "MeasureView/UnitConvert.h"
#include "MeasureView/MeasureDataSet.h"
namespace Qly {

MeasureCircle2Circle::MeasureCircle2Circle(MeasureDataSet *parent)
    :MeasureElement(parent)
{
    m_measureType = Circle2Circle;
    m_results_pix.resize(9);
    m_results_um.resize(9);
    m_keyPoints_pix.resize(7); //第7个用来存两个圆心的中点坐标
    m_keyPoints_um.resize(7);

    m_textTemplate = parent->m_textTemplate_MeasureCircle2Circle;
}


int MeasureCircle2Circle::mouseLButtonPress(QPointF point_pix, QPointF point_um)
{
    if( m_measureState == DS_IDLE )
    {
        m_keyPoints_pix[0] = point_pix; //记录第1个点
        m_keyPoints_um[0] = point_um;

        m_keyPoints_pix[1] = point_pix; //记录第1个点
        m_keyPoints_um[1] = point_um;
        m_measureState = DS_STATE1;
        return m_measureState;
    }
    if(m_measureState == DS_STATE1)
    {
        m_keyPoints_pix[1] = point_pix; //记录第2个点
        m_keyPoints_um[1] = point_um;

        m_keyPoints_pix[2] = point_pix; //记录第1个点
        m_keyPoints_um[2] = point_um;
        m_measureState = DS_STATE2;
        return m_measureState;
    }
    if(m_measureState == DS_STATE2)
    {
        m_keyPoints_pix[2] = point_pix; //记录第3个点
        m_keyPoints_um[2] = point_um;
        compute();
        m_measureState = DS_STATE3;
        return m_measureState;
    }
    if(m_measureState == DS_STATE3)
    {
        m_keyPoints_pix[3] = point_pix; //记录第4个点
        m_keyPoints_um[3] = point_um;

        m_keyPoints_pix[4] = point_pix; //记录第4个点
        m_keyPoints_um[4] = point_um;
        m_measureState = DS_STATE4;
        return m_measureState;
    }
    if(m_measureState == DS_STATE4)
    {
        m_keyPoints_pix[4] = point_pix; //记录第5个点
        m_keyPoints_um[4] = point_um;

        m_keyPoints_pix[5] = point_pix; //记录第5个点
        m_keyPoints_um[5] = point_um;
        m_measureState = DS_STATE5;
        return m_measureState;
    }
    if(m_measureState == DS_STATE5)
    {
        m_keyPoints_pix[5] = point_pix; //记录第6个点
        m_keyPoints_um[5] = point_um;
        compute();
        updateText(true);

        m_measureState = DS_FINISH;
        return m_measureState;
    }
    return m_measureState;
}

int MeasureCircle2Circle::mouseMove(QPointF point_pix, QPointF point_um)
{
    if(m_measureState == DS_STATE2)
    {
        m_keyPoints_pix[2] = point_pix;
        m_keyPoints_um[2] = point_um;
        compute();
        return m_measureState;
    }
    if(m_measureState == DS_STATE5)
    {
        m_keyPoints_pix[5] = point_pix;
        m_keyPoints_um[5] = point_um;
        compute();
        return m_measureState;
    }
    return m_measureState;
}

void buildCircle(const QPointF &p1, const QPointF &p2, const QPointF &p3, QPointF &center, double &radius)
{
    double x1 = p1.x();
    double y1 = p1.y();
    double x2 = p2.x();
    double y2 = p2.y();
    double x3 = p3.x();
    double y3 = p3.y();

    double a, b, c, d, e, f, g, x, y;
    a = 2 * (x2 - x1);
    b = 2 * (y2 - y1);
    c = x2 * x2 + y2 * y2 - x1 * x1 - y1 * y1;
    d = 2 * (x3 - x2);
    e = 2 * (y3 - y2);
    f = x3 * x3 + y3 * y3 - x2 * x2 - y2 * y2;
    g = b * d - e * a;
    if(fabs(g) < 1e-5)
    {
        center.setX(0);
        center.setY(0);
        radius = 0.0;
        return ;
    }
    x = (b * f - e * c) / g;
    y = (d * c - a * f) / g;

    center.setX(x);
    center.setY(y);
    radius = sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
}

void MeasureCircle2Circle::paint(QPainter &painter)
{
    int x, y, width, height;
    if( m_measureState != DS_IDLE )
    {
        painter.save();
        painter.setPen(m_pen);

        drawCross(painter, m_keyPoints_pix[0]);
        drawCross(painter, m_keyPoints_pix[1]);
        if( m_measureState >= DS_STATE2 )
        {
            drawCross(painter, m_keyPoints_pix[2]);

            x = m_results_pix[0] - m_results_pix[2];
            y = m_results_pix[1] - m_results_pix[2];
            width = m_results_pix[2] * 2;
            height = m_results_pix[2] * 2;
            painter.drawArc ( x, y, width, height, 0, 16 * 360 );

            drawCross(painter, QPointF(m_results_pix[0], m_results_pix[1]));
        }
        if( m_measureState >= DS_STATE4 )
        {
            drawCross(painter, m_keyPoints_pix[3]);
            drawCross(painter, m_keyPoints_pix[4]);
        }
        if( m_measureState >= DS_STATE5 )
        {
            drawCross(painter, m_keyPoints_pix[5]);

            x = m_results_pix[3] - m_results_pix[5];
            y = m_results_pix[4] - m_results_pix[5];
            width = m_results_pix[5] * 2;
            height = m_results_pix[5] * 2;
            painter.drawArc ( x, y, width, height, 0, 16 * 360 );

            drawCross(painter, QPointF(m_results_pix[3], m_results_pix[4]));

            painter.drawLine(QPointF(m_results_pix[0], m_results_pix[1]), QPointF(m_results_pix[3], m_results_pix[4]));
            m_textBlock.draw(painter);
        }
        if(m_textMoving)
        {
            QPen pen = m_pen;
            pen.setStyle(Qt::DashDotLine);
            painter.setPen(pen);
            QPointF p = m_textBlock.anchorPoint();
            painter.drawLine(p, m_keyPoints_pix[6]);
            painter.setPen(m_pen);
        }
        painter.restore();
    }
}

//int MeasureCircle2Circle::setLens(int oldLens, int newLens, int method)
//{
//    if(oldLens == newLens || oldLens == -1) return 0;// 这时不需要更新任何数据
//    if(m_keyPoints_pix.size() != m_keyPoints_um.size()) //这里表示出现了错误，也应该退出
//    {
//        return 0;
//    }
//    LensManager & lens = LensManager::getInstance();
//    if(method == 0)//只更新长度的数值，图元在图像上的位置不变
//    {
//        double new_pixelSize = lens.currentLens().pixelSize_um;
//        for(int  i = 0; i < m_keyPoints_pix.size(); ++i)
//        {
//            m_keyPoints_um[i] = m_keyPoints_pix[i] * new_pixelSize;
//        }
//    }
//    else
//    {
//        LensData & oldData = lens.lensByIndex(oldLens);
//        LensData & newData = lens.currentLens();
//        double dx = (newData.xCompensate_um - oldData.xCompensate_um);
//        double dy = (newData.yCompensate_um - oldData.yCompensate_um);
//        for(int  i = 0; i < m_keyPoints_pix.size(); ++i)
//        {
//            m_keyPoints_pix[i] = (m_keyPoints_um[i] + QPointF(dx, dy)) / newData.pixelSize_um;
//        }
//    }
//    compute();
//    updateText();
//    return 1;
//}

void MeasureCircle2Circle::compute()
{
    QPointF c;
    buildCircle(m_keyPoints_pix[0], m_keyPoints_pix[1], m_keyPoints_pix[2], c, m_results_pix[2]);
    m_results_pix[0] = c.x();
    m_results_pix[1] = c.y();

//    double ps = LensManager::getInstance().pixelSize_um();
    m_results_um[0] = m_pParent->m_pixSize_um * m_results_pix[0];
    m_results_um[1] = m_pParent->m_pixSize_um * m_results_pix[1];
    m_results_um[2] = m_pParent->m_pixSize_um * m_results_pix[2];

    if(m_measureState == DS_STATE5 || m_measureState == DS_FINISH)
    {
        buildCircle(m_keyPoints_pix[3], m_keyPoints_pix[4], m_keyPoints_pix[5], c, m_results_pix[5]);
        m_results_pix[3] = c.x();
        m_results_pix[4] = c.y();

        m_results_pix[6] = m_results_pix[3] - m_results_pix[0];
        m_results_pix[7] = m_results_pix[4] - m_results_pix[1];
        m_results_pix[8] = hypot(m_results_pix[6], m_results_pix[7]);

        m_results_um[3] = m_pParent->m_pixSize_um * m_results_pix[3];
        m_results_um[4] = m_pParent->m_pixSize_um * m_results_pix[4];
        m_results_um[5] = m_pParent->m_pixSize_um * m_results_pix[5];
        m_results_um[6] = m_pParent->m_pixSize_um * m_results_pix[6];
        m_results_um[7] = m_pParent->m_pixSize_um * m_results_pix[7];
        m_results_um[8] = m_pParent->m_pixSize_um * m_results_pix[8];
    }
}


void MeasureCircle2Circle::updateText(bool updatePosition)
{
    QString text = m_textTemplate;
    QString str, unitStr;
    m_pParent->m_unitConvert_MeasureCircle2Circle.replaceLength(text, m_results_um[8], "@length", "@unit");


    QString str3 = QString::number(m_id);
    text.replace("@id", str3, Qt::CaseSensitive);

    m_textBlock.setText(text);
    if(updatePosition)
    {
        m_keyPoints_pix[6] = QPointF( (m_results_pix[0] + m_results_pix[3]) / 2.0, (m_results_pix[1] + m_results_pix[4]) / 2.0 );
        m_keyPoints_um[6] = QPointF( (m_results_um[0] + m_results_um[3]) / 2.0, (m_results_um[1] + m_results_um[4]) / 2.0 );
        m_textBlock.moveTo(m_keyPoints_pix[6], m_keyPoints_um[6]);
    }
}

}
